package com.tengju.user.infrastructure.schedule;

import com.tengju.data.domain.model.service.DataVersionService;
import com.tengju.support.domain.model.alert.AlertEvent;
import com.tengju.support.domain.model.alert.AlertService;
import com.tengju.user.application.archives.StarUpcomingService;
import com.tengju.user.domain.model.sign.StarChangeNoticeRecord;
import com.tengju.user.domain.model.sign.StarChangeNoticeTypeEnum;
import com.tengju.user.domain.model.sign.StarSignInfoRepository;
import com.tengju.user.domain.model.user.StarLevelEnum;
import com.tengju.user.domain.model.user.UserIdCode;
import com.tengju.user.domain.model.user.UserInfo;
import com.tengju.user.domain.service.RemoteUserService;
import com.tengju.user.domain.shared.CastUtil;
import com.tengju.user.domain.shared.DateUtil;
import com.tengju.user.infrastructure.shared.ScheduleJobException;
import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.handler.annotation.XxlJob;
import com.xxl.job.core.log.XxlJobLogger;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author chenhang
 * @Date 2021/11/15
 */
@Component
@Slf4j
@RequiredArgsConstructor(onConstructor_ = {@Autowired})
public class StarUpcomingSmsJob {

    private final DataVersionService dataVersionService;
    private final StarSignInfoRepository starSignInfoRepository;
    private final RemoteUserService remoteUserService;
    private final StarUpcomingService starUpcomingService;
    private final AlertService alertService;

    private final String jobName = "星级即将晋升用户短信提醒任务";

    private final String jobKey = "starUpcomingSmsJob";

    private Integer LIMIT_NUM = 1000;

    /**
     * 首次满足即将晋升一星条件的经销商，发送短信提醒
     * 重复满足条件的不会重复发送，每人只发送一次
     * @param params
     * @return
     */
    @XxlJob("starUpcomingSmsJob")
    public ReturnT<String> execute(String params) {
        XxlJobLogger.log("{} 开始, param:{}", jobName, params);
        log.info("{} 开始, param:{}", jobName, params);
        long start = System.currentTimeMillis();
        try {
            LocalDateTime noticeDate = LocalDateTime.now();
            if (!StringUtils.isBlank(params)) {
                noticeDate = DateUtil.dateToLocalDateTime(DateUtil.parseStringToDate(DateUtil.DATE_DAY_FORMAT,params));
            }
            noticeDate = noticeDate.withHour(0).withMinute(0).withSecond(0).withNano(0);
            int dayInt = CastUtil.castInt(DateUtil.formartLocalDateTime(DateUtil.DATE_FORMAT,noticeDate));
            if (!dataVersionService.checkStarNoticeVersion(dayInt)) {
                throw new ScheduleJobException("即将晋升名单数据还未准备好！");
            }
            int count = starSignInfoRepository.countStarNotice(noticeDate, StarChangeNoticeTypeEnum.UPCOMING);
            int offset = 0;
            while (offset <= count) {
                List<StarChangeNoticeRecord> starUpcomingRecordList = starSignInfoRepository.listStarNotice(
                        noticeDate,
                        StarChangeNoticeTypeEnum.UPCOMING,
                        offset,
                        LIMIT_NUM);
                offset += LIMIT_NUM;
                if (CollectionUtils.isEmpty(starUpcomingRecordList)) {
                    continue;
                }
                List<UserIdCode> userIdCodes = starUpcomingRecordList.stream()
                        .filter(v -> StarLevelEnum.CITY_STAR_ONE.getCode().equals(v.getTargetStarLevel()))
                        .map(StarChangeNoticeRecord::getIdCode)
                        .collect(Collectors.toList());
                List<UserInfo> userInfoList = remoteUserService.getByIdList(userIdCodes);
                Map<UserIdCode,UserInfo> userInfoMap = new HashMap<>();
                if (!CollectionUtils.isEmpty(userInfoList)) {
                    userInfoMap = userInfoList.stream()
                            .collect(Collectors.toMap(UserInfo::getIdCode, v -> v,(v1, v2) -> v1));
                }
                for (UserIdCode userIdCode : userIdCodes) {
                    try {
                        starUpcomingService.sendSmsStarUpcoming(userIdCode,userInfoMap.get(userIdCode));
                    } catch (Exception e) {
                        log.error("即将晋升短信发送异常：idCode: {}",userIdCode.getValue(), e);
                        AlertEvent alertEvent = new AlertEvent("星级即将晋升用户短信提醒任务异常");
                        alertEvent.addItem("异常信息",e.getMessage());
                        alertService.alert(alertEvent);
                    }
                }
            }
        } catch (Exception e) {
            log.error("{}, jobError", jobName, e);
            AlertEvent event = new AlertEvent(jobName + "异常");
            event.addItem("异常",e.getMessage());
            alertService.alert(event);
            return ReturnT.FAIL;
        }
        XxlJobLogger.log("{}} 结束, param:{}, 耗时为:{}ms", jobName, params, System.currentTimeMillis() - start);
        return ReturnT.SUCCESS;
    }


}
